Conversation
…al-credit-purchases # Conflicts: # packages/db/src/migrations/meta/0115_snapshot.json # packages/db/src/migrations/meta/0116_snapshot.json # packages/db/src/migrations/meta/0117_snapshot.json # packages/db/src/migrations/meta/_journal.json # pnpm-lock.yaml
…al-credit-purchases # Conflicts: # apps/web/package.json # apps/web/src/routers/kilo-pass-router.ts # packages/db/src/migrations/meta/0123_snapshot.json # packages/db/src/migrations/meta/_journal.json # pnpm-lock.yaml # pnpm-workspace.yaml
| try { | ||
| await showManageSubscriptionsIOS(); | ||
| await invalidateKiloPassState(); | ||
| setTimeout(() => { |
There was a problem hiding this comment.
WARNING: Uncleared setTimeout causes a potential memory leak / stale state update
If the component unmounts within 2 seconds of the user returning from the App Store sheet, invalidateKiloPassState() will fire on an unmounted component. This is a classic leak pattern in React Native.
Consider using a ref to track mount state, or simply rely on the useEffect invalidation in useStoreKiloPassPurchase / react-query's own window-focus refetch instead of a delayed re-check:
| setTimeout(() => { | |
| void invalidateKiloPassState(); |
| showError: (message: string) => void; | ||
| }; | ||
|
|
||
| const sharedPurchaseCompletions = new Map<string, Promise<boolean>>(); |
There was a problem hiding this comment.
WARNING: Module-level mutable state is a potential memory leak in React Native
sharedPurchaseCompletions and lastPurchaseErrorToast are module-level singletons that accumulate state across the app's lifetime and are never cleaned up. In React Native's Metro bundler, modules persist across hot reloads (Fast Refresh), so test/dev scenarios can see stale entries. More critically, sharedPurchaseCompletions holds Promise<boolean> references that may keep closures alive.
This is intentional cross-instance deduplication, but consider documenting this explicitly and ensuring entries are always deleted after completion (they are, via .delete(purchaseId)), and confirm no error paths skip the delete.
Code Review SummaryStatus: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)CRITICAL
WARNING
SUGGESTION
Other Observations (not in diff)CRITICAL — GDPR soft-delete gap ( The AGENTS.md rules explicitly require: "When adding PII … to the database — whether as a new table or a new column — you MUST also update the GDPR soft-delete flow in This PR adds:
Recommendation:
SUGGESTION — stripeSubscriptionId: selected.stripeSubscriptionId ?? selected.providerSubscriptionId ?? '',This silently reuses a Stripe-named field to carry an Apple Files Reviewed (56 files)
Fix these issues in Kilo Cloud Reviewed by claude-sonnet-4.6 · 7,349,074 tokens |
Summary
This PR replaces the original one-time Apple credit purchase experiment with App Store-managed Kilo Pass subscriptions across the data model, backend APIs, web management surfaces, and mobile purchase flow.
/device-authto show the signed-in account plus a sign-out path before approving a device.Verification
Visual Changes
Visual changes exist for the mobile Kilo Pass/profile purchase flow and web account-management surfaces, but screenshots are not attached in this description update.
Reviewer Notes
APPLE_IAP_ENVIRONMENT.